From 8e151460265f04c7bf4a981b5f97f252a0444c27 Mon Sep 17 00:00:00 2001 From: lat9nq <22451773+lat9nq@users.noreply.github.com> Date: Wed, 10 May 2023 17:57:25 -0400 Subject: configure_system: Implement with for loop --- src/common/settings.cpp | 1 + src/common/settings.h | 114 +++++- src/core/core.cpp | 20 +- src/core/file_sys/control_metadata.cpp | 3 +- src/core/file_sys/patch_manager.cpp | 4 +- src/core/hle/service/ns/ns.cpp | 2 +- src/core/hle/service/set/set.cpp | 10 +- src/yuzu/configuration/config.cpp | 2 + src/yuzu/configuration/configure_dialog.cpp | 2 +- src/yuzu/configuration/configure_graphics.cpp | 2 +- src/yuzu/configuration/configure_per_game.cpp | 2 +- src/yuzu/configuration/configure_system.cpp | 232 +++++------- src/yuzu/configuration/configure_system.h | 17 +- src/yuzu/configuration/configure_system.ui | 509 +++----------------------- src/yuzu/configuration/shared_translation.cpp | 43 ++- src/yuzu/configuration/shared_widget.cpp | 179 ++++++++- src/yuzu/configuration/shared_widget.h | 13 +- src/yuzu_cmd/config.cpp | 1 + 18 files changed, 508 insertions(+), 648 deletions(-) diff --git a/src/common/settings.cpp b/src/common/settings.cpp index b7a0c063f..605fe7f86 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -162,6 +162,7 @@ const char* TranslateCategory(Category category) { case Category::RendererDebug: return "Renderer"; case Category::System: + case Category::SystemAudio: return "System"; case Category::DataStorage: return "Data Storage"; diff --git a/src/common/settings.h b/src/common/settings.h index fdadb06a1..1f95bd7d5 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -20,6 +20,86 @@ namespace Settings { +enum class Language : u32 { + Japanese, + EnglishAmerican, + French, + German, + Italian, + Spanish, + Chinese, + Korean, + Dutch, + Portuguese, + Russian, + Taiwanese, + EnglishBritish, + FrenchCanadian, + SpanishLatin, + ChineseSimplified, + ChineseTraditional, + PortugueseBrazilian, +}; + +enum class Region : u32 { + Japan, + USA, + Europe, + Australia, + China, + Korea, + Taiwan, +}; + +enum class TimeZone : u32 { + Auto, + Default, + CET, + CST6CDT, + Cuba, + EET, + Egypt, + Eire, + EST, + EST5EDT, + GB, + GBEire, + GMT, + GMTPlusZero, + GMTMinusZero, + GMTZero, + Greenwich, + Hongkong, + HST, + Iceland, + Iran, + Israel, + Jamaica, + Japan, + Kwajalein, + Libya, + MET, + MST, + MST7MDT, + Navajo, + NZ, + NZCHAT, + Poland, + Portugal, + PRC, + PST8PDT, + ROC, + ROK, + Singapore, + Turkey, + UCT, + Universal, + UTC, + W_SU, + WET, + Zulu, +}; + enum class AnisotropyMode : u32 { Automatic = 0, Default = 1, @@ -134,6 +214,7 @@ enum class Category : u32 { RendererAdvanced, RendererDebug, System, + SystemAudio, DataStorage, Debugging, DebuggingGraphics, @@ -810,22 +891,31 @@ struct Values { SwitchableSetting bg_blue{linkage, 0, "bg_blue", Category::Renderer, true, true}; // System - SwitchableSetting rng_seed_enabled{linkage, false, "rng_seed_enabled", Category::System}; - SwitchableSetting rng_seed{linkage, 0, "rng_seed", Category::System}; - Setting device_name{linkage, "Yuzu", "device_name", Category::System}; + SwitchableSetting rng_seed_enabled{linkage, false, "rng_seed_enabled", + Category::System, true, true}; + SwitchableSetting rng_seed{linkage, 0, "rng_seed", Category::System, true, true}; + Setting device_name{linkage, "Yuzu", "device_name", Category::System, true, true}; // Measured in seconds since epoch - Setting custom_rtc_enabled{linkage, false, "custom_rtc_enabled", Category::System}; - Setting custom_rtc{linkage, 0, "custom_rtc", Category::System}; + SwitchableSetting custom_rtc_enabled{linkage, false, "custom_rtc_enabled", + Category::System, true, true}; + SwitchableSetting custom_rtc{linkage, 0, "custom_rtc", Category::System, true, true}; // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc` s64 custom_rtc_differential; Setting current_user{linkage, 0, "current_user", Category::System}; - SwitchableSetting language_index{linkage, 1, 0, 17, "language_index", - Category::System}; - SwitchableSetting region_index{linkage, 1, 0, 6, "region_index", Category::System}; - SwitchableSetting time_zone_index{linkage, 0, 0, 45, "time_zone_index", - Category::System}; - SwitchableSetting sound_index{linkage, 1, 0, 2, "sound_index", Category::System}; + SwitchableSetting language_index{linkage, + Language::EnglishAmerican, + Language::Japanese, + Language::PortugueseBrazilian, + "language_index", + Category::System}; + SwitchableSetting region_index{linkage, Region::USA, Region::Japan, + Region::Taiwan, "region_index", Category::System}; + SwitchableSetting time_zone_index{linkage, TimeZone::Auto, + TimeZone::Auto, TimeZone::Zulu, + "time_zone_index", Category::System}; + SwitchableSetting sound_index{ + linkage, 1, 0, 2, "sound_index", Category::SystemAudio}; SwitchableSetting use_docked_mode{linkage, true, "use_docked_mode", Category::System}; @@ -837,7 +927,7 @@ struct Values { #ifdef _WIN32 true #else - false + false #endif }; Setting controller_navigation{linkage, true, "controller_navigation", Category::Controls}; diff --git a/src/core/core.cpp b/src/core/core.cpp index da1baa892..e2902a91f 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -145,13 +145,7 @@ struct System::Impl { core_timing.SetMulticore(is_multicore); core_timing.Initialize([&system]() { system.RegisterHostThread(); }); - const auto posix_time = std::chrono::system_clock::now().time_since_epoch(); - const auto current_time = - std::chrono::duration_cast(posix_time).count(); - Settings::values.custom_rtc_differential = - (Settings::values.custom_rtc_enabled ? Settings::values.custom_rtc.GetValue() - : current_time) - - current_time; + RefreshTime(); // Create a default fs if one doesn't already exist. if (virtual_filesystem == nullptr) { @@ -188,6 +182,16 @@ struct System::Impl { Initialize(system); } + void RefreshTime() { + const auto posix_time = std::chrono::system_clock::now().time_since_epoch(); + const auto current_time = + std::chrono::duration_cast(posix_time).count(); + Settings::values.custom_rtc_differential = + (Settings::values.custom_rtc_enabled ? Settings::values.custom_rtc.GetValue() + : current_time) - + current_time; + } + void Run() { std::unique_lock lk(suspend_guard); @@ -1022,6 +1026,8 @@ void System::Exit() { } void System::ApplySettings() { + impl->RefreshTime(); + if (IsPoweredOn()) { Renderer().RefreshBaseSettings(); } diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp index cd9ac2e75..0697c29ae 100644 --- a/src/core/file_sys/control_metadata.cpp +++ b/src/core/file_sys/control_metadata.cpp @@ -68,7 +68,8 @@ NACP::NACP(VirtualFile file) { NACP::~NACP() = default; const LanguageEntry& NACP::GetLanguageEntry() const { - Language language = language_to_codes[Settings::values.language_index.GetValue()]; + Language language = + language_to_codes[static_cast(Settings::values.language_index.GetValue())]; { const auto& language_entry = raw.language_entries.at(static_cast(language)); diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp index d3286b352..2ba1b34a4 100644 --- a/src/core/file_sys/patch_manager.cpp +++ b/src/core/file_sys/patch_manager.cpp @@ -626,8 +626,8 @@ PatchManager::Metadata PatchManager::ParseControlNCA(const NCA& nca) const { auto nacp = nacp_file == nullptr ? nullptr : std::make_unique(nacp_file); // Get language code from settings - const auto language_code = - Service::Set::GetLanguageCodeFromIndex(Settings::values.language_index.GetValue()); + const auto language_code = Service::Set::GetLanguageCodeFromIndex( + static_cast(Settings::values.language_index.GetValue())); // Convert to application language and get priority list const auto application_language = diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp index 376067a95..91c5a2182 100644 --- a/src/core/hle/service/ns/ns.cpp +++ b/src/core/hle/service/ns/ns.cpp @@ -409,7 +409,7 @@ ResultVal IApplicationManagerInterface::GetApplicationDesiredLanguage( // Get language code from settings const auto language_code = - Set::GetLanguageCodeFromIndex(Settings::values.language_index.GetValue()); + Set::GetLanguageCodeFromIndex(static_cast(Settings::values.language_index.GetValue())); // Convert to application language, get priority list const auto application_language = ConvertToApplicationLanguage(language_code); diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index f5788b481..83f888c54 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp @@ -93,7 +93,8 @@ void GetAvailableLanguageCodesImpl(HLERequestContext& ctx, std::size_t max_entri } void GetKeyCodeMapImpl(HLERequestContext& ctx) { - const auto language_code = available_language_codes[Settings::values.language_index.GetValue()]; + const auto language_code = + available_language_codes[static_cast(Settings::values.language_index.GetValue())]; const auto key_code = std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), [=](const auto& element) { return element.first == language_code; }); @@ -162,7 +163,7 @@ void SET::GetQuestFlag(HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(static_cast(Settings::values.quest_flag.GetValue())); + rb.Push(static_cast(Settings::values.quest_flag.GetValue())); } void SET::GetLanguageCode(HLERequestContext& ctx) { @@ -170,7 +171,8 @@ void SET::GetLanguageCode(HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); - rb.PushEnum(available_language_codes[Settings::values.language_index.GetValue()]); + rb.PushEnum( + available_language_codes[static_cast(Settings::values.language_index.GetValue())]); } void SET::GetRegionCode(HLERequestContext& ctx) { @@ -178,7 +180,7 @@ void SET::GetRegionCode(HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(Settings::values.region_index.GetValue()); + rb.Push(static_cast(Settings::values.region_index.GetValue())); } void SET::GetKeyCodeMap(HLERequestContext& ctx) { diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 3181a9528..28ee5d492 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -696,6 +696,7 @@ void Config::ReadSystemValues() { qt_config->beginGroup(QStringLiteral("System")); ReadCategory(Settings::Category::System); + ReadCategory(Settings::Category::SystemAudio); qt_config->endGroup(); } @@ -1134,6 +1135,7 @@ void Config::SaveSystemValues() { qt_config->beginGroup(QStringLiteral("System")); WriteCategory(Settings::Category::System); + WriteCategory(Settings::Category::SystemAudio); qt_config->endGroup(); } diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index 8baa8de1e..3a94fee9e 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -48,7 +48,7 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, input_tab{std::make_unique(system_, this)}, network_tab{std::make_unique(system_, this)}, profile_tab{std::make_unique(system_, this)}, - system_tab{std::make_unique(system_, nullptr, this)}, + system_tab{std::make_unique(system_, nullptr, *translations, this)}, ui_tab{std::make_unique(system_, this)}, web_tab{std::make_unique( this)} { Settings::SetConfiguringGlobal(true); diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index ae3cf269f..977aed42d 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp @@ -240,7 +240,7 @@ void ConfigureGraphics::Setup() { return new ConfigurationShared::Widget( setting, translations, this, runtime_lock, apply_funcs, ConfigurationShared::RequestType::SpinBox, true, 1.0f, - &Settings::values.speed_limit, QStringLiteral("%")); + &Settings::values.speed_limit, "%"); } else { return new ConfigurationShared::Widget(setting, translations, this, runtime_lock, apply_funcs); diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index 5548fc2ba..c39855334 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp @@ -58,7 +58,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st system_, vk_device_records, [&]() { graphics_advanced_tab->ExposeComputeOption(); }, tab_group, *translations, this); input_tab = std::make_unique(system_, game_config.get(), this); - system_tab = std::make_unique(system_, tab_group, this); + system_tab = std::make_unique(system_, tab_group, *translations, this); ui->setupUi(this); diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp index 4872a475b..dedbad57f 100644 --- a/src/yuzu/configuration/configure_system.cpp +++ b/src/yuzu/configuration/configure_system.cpp @@ -2,17 +2,22 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include +#include #include +#include #include #include +#include #include #include "common/settings.h" #include "core/core.h" #include "core/hle/service/time/time_manager.h" #include "ui_configure_system.h" +#include "yuzu/configuration/config.h" #include "yuzu/configuration/configuration_shared.h" #include "yuzu/configuration/configure_system.h" +#include "yuzu/configuration/shared_widget.h" constexpr std::array LOCALE_BLOCKLIST{ // pzzefezrpnkzeidfej @@ -39,44 +44,42 @@ static bool IsValidLocale(u32 region_index, u32 language_index) { ConfigureSystem::ConfigureSystem( Core::System& system_, std::shared_ptr> group, - QWidget* parent) - : Tab(group, parent), ui{std::make_unique()}, system{system_} { + ConfigurationShared::TranslationMap& translations_, QWidget* parent) + : Tab(group, parent), ui{std::make_unique()}, system{system_}, + translations{translations_} { ui->setupUi(this); - connect(ui->rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](int state) { - ui->rng_seed_edit->setEnabled(state == Qt::Checked); + Setup(); + + connect(rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](int state) { + rng_seed_edit->setEnabled(state == Qt::Checked); if (state != Qt::Checked) { - ui->rng_seed_edit->setText(QStringLiteral("00000000")); + rng_seed_edit->setText(QStringLiteral("00000000")); } }); - connect(ui->custom_rtc_checkbox, &QCheckBox::stateChanged, this, [this](int state) { - ui->custom_rtc_edit->setEnabled(state == Qt::Checked); + connect(custom_rtc_checkbox, &QCheckBox::stateChanged, this, [this](int state) { + custom_rtc_edit->setEnabled(state == Qt::Checked); if (state != Qt::Checked) { - ui->custom_rtc_edit->setDateTime(QDateTime::currentDateTime()); + custom_rtc_edit->setDateTime(QDateTime::currentDateTime()); } }); const auto locale_check = [this](int index) { - const auto region_index = ConfigurationShared::GetComboboxIndex( - Settings::values.region_index.GetValue(true), ui->combo_region); - const auto language_index = ConfigurationShared::GetComboboxIndex( - Settings::values.language_index.GetValue(true), ui->combo_language); + const auto region_index = combo_region->currentIndex(); + const auto language_index = combo_language->currentIndex(); const bool valid_locale = IsValidLocale(region_index, language_index); ui->label_warn_invalid_locale->setVisible(!valid_locale); if (!valid_locale) { ui->label_warn_invalid_locale->setText( tr("Warning: \"%1\" is not a valid language for region \"%2\"") - .arg(ui->combo_language->currentText()) - .arg(ui->combo_region->currentText())); + .arg(combo_language->currentText()) + .arg(combo_region->currentText())); } }; - connect(ui->combo_language, qOverload(&QComboBox::currentIndexChanged), this, - locale_check); - connect(ui->combo_region, qOverload(&QComboBox::currentIndexChanged), this, locale_check); - - SetupPerGameUI(); + connect(combo_language, qOverload(&QComboBox::currentIndexChanged), this, locale_check); + connect(combo_region, qOverload(&QComboBox::currentIndexChanged), this, locale_check); SetConfiguration(); } @@ -95,137 +98,94 @@ void ConfigureSystem::RetranslateUI() { ui->retranslateUi(this); } -void ConfigureSystem::SetConfiguration() { - enabled = !system.IsPoweredOn(); - const auto rng_seed = QStringLiteral("%1") - .arg(Settings::values.rng_seed.GetValue(), 8, 16, QLatin1Char{'0'}) - .toUpper(); - const auto rtc_time = Settings::values.custom_rtc_enabled - ? Settings::values.custom_rtc.GetValue() - : QDateTime::currentSecsSinceEpoch(); - - ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed_enabled.GetValue()); - ui->rng_seed_edit->setEnabled(Settings::values.rng_seed_enabled.GetValue() && - Settings::values.rng_seed.UsingGlobal()); - ui->rng_seed_edit->setText(rng_seed); - - ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc_enabled.GetValue()); - ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc_enabled.GetValue()); - ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time)); - ui->device_name_edit->setText( - QString::fromUtf8(Settings::values.device_name.GetValue().c_str())); - ui->use_unsafe_extended_memory_layout->setEnabled(enabled); - ui->use_unsafe_extended_memory_layout->setChecked( - Settings::values.use_unsafe_extended_memory_layout.GetValue()); - - if (Settings::IsConfiguringGlobal()) { - ui->combo_language->setCurrentIndex(Settings::values.language_index.GetValue()); - ui->combo_region->setCurrentIndex(Settings::values.region_index.GetValue()); - ui->combo_time_zone->setCurrentIndex(Settings::values.time_zone_index.GetValue()); - } else { - ConfigurationShared::SetPerGameSetting(ui->combo_language, - &Settings::values.language_index); - ConfigurationShared::SetPerGameSetting(ui->combo_region, &Settings::values.region_index); - ConfigurationShared::SetPerGameSetting(ui->combo_time_zone, - &Settings::values.time_zone_index); - - ConfigurationShared::SetHighlight(ui->label_language, - !Settings::values.language_index.UsingGlobal()); - ConfigurationShared::SetHighlight(ui->label_region, - !Settings::values.region_index.UsingGlobal()); - ConfigurationShared::SetHighlight(ui->label_timezone, - !Settings::values.time_zone_index.UsingGlobal()); - } -} +void ConfigureSystem::Setup() { + const bool runtime_lock = !system.IsPoweredOn(); + auto& core_layout = *ui->core_widget->layout(); + auto& system_layout = *ui->system_widget->layout(); -void ConfigureSystem::ReadSystemSettings() {} + std::map core_hold{}; + std::map> system_hold{}; -void ConfigureSystem::ApplyConfiguration() { - // Allow setting custom RTC even if system is powered on, - // to allow in-game time to be fast forwarded - if (Settings::IsConfiguringGlobal()) { - if (ui->custom_rtc_checkbox->isChecked()) { - Settings::values.custom_rtc_enabled = true; - Settings::values.custom_rtc = ui->custom_rtc_edit->dateTime().toSecsSinceEpoch(); - if (system.IsPoweredOn()) { - const s64 posix_time{Settings::values.custom_rtc.GetValue() + - Service::Time::TimeManager::GetExternalTimeZoneOffset()}; - system.GetTimeManager().UpdateLocalSystemClockTime(posix_time); - } - } else { - Settings::values.custom_rtc_enabled = false; + std::forward_list settings; + auto push = [&settings](std::forward_list& list) { + for (auto setting : list) { + settings.push_front(setting); } - } + }; - Settings::values.device_name = ui->device_name_edit->text().toStdString(); + push(Settings::values.linkage.by_category[Settings::Category::Core]); + push(Settings::values.linkage.by_category[Settings::Category::System]); + + for (auto setting : settings) { + ConfigurationShared::Widget* widget = [=]() { + if (setting->Id() == Settings::values.custom_rtc_enabled.Id()) { + return new ConfigurationShared::Widget( + setting, translations, this, runtime_lock, apply_funcs, + ConfigurationShared::RequestType::DateTimeEdit, true, 1.0f, + &Settings::values.custom_rtc); + } else if (setting->Id() == Settings::values.rng_seed_enabled.Id()) { + return new ConfigurationShared::Widget(setting, translations, this, runtime_lock, + apply_funcs, + ConfigurationShared::RequestType::HexEdit, + true, 1.0f, &Settings::values.rng_seed); + } else { + return new ConfigurationShared::Widget(setting, translations, this, runtime_lock, + + apply_funcs); + } + }(); - if (!enabled) { - return; - } + if (!widget->Valid()) { + delete widget; + continue; + } + + if (setting->Id() == Settings::values.rng_seed_enabled.Id()) { + rng_seed_checkbox = widget->checkbox; + rng_seed_edit = widget->line_edit; - ConfigurationShared::ApplyPerGameSetting(&Settings::values.language_index, ui->combo_language); - ConfigurationShared::ApplyPerGameSetting(&Settings::values.region_index, ui->combo_region); - ConfigurationShared::ApplyPerGameSetting(&Settings::values.time_zone_index, - ui->combo_time_zone); - ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_unsafe_extended_memory_layout, - ui->use_unsafe_extended_memory_layout, - use_unsafe_extended_memory_layout); - - if (Settings::IsConfiguringGlobal()) { - // Guard if during game and set to game-specific value - if (Settings::values.rng_seed.UsingGlobal()) { - Settings::values.rng_seed_enabled = ui->rng_seed_checkbox->isChecked(); - if (ui->rng_seed_checkbox->isChecked()) { - Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toUInt(nullptr, 16)); + if (!Settings::values.rng_seed_enabled.GetValue()) { + rng_seed_edit->setEnabled(false); } + } else if (setting->Id() == Settings::values.custom_rtc_enabled.Id()) { + custom_rtc_checkbox = widget->checkbox; + custom_rtc_edit = widget->date_time_edit; + + custom_rtc_edit->setEnabled(Settings::values.custom_rtc_enabled.GetValue()); + } else if (setting->Id() == Settings::values.region_index.Id()) { + + combo_region = widget->combobox; + } else if (setting->Id() == Settings::values.language_index.Id()) { + combo_language = widget->combobox; } - } else { - switch (use_rng_seed) { - case ConfigurationShared::CheckState::On: - case ConfigurationShared::CheckState::Off: - Settings::values.rng_seed_enabled.SetGlobal(false); - Settings::values.rng_seed.SetGlobal(false); - if (ui->rng_seed_checkbox->isChecked()) { - Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toUInt(nullptr, 16)); - } - break; - case ConfigurationShared::CheckState::Global: - Settings::values.rng_seed_enabled.SetGlobal(true); - Settings::values.rng_seed.SetGlobal(true); + + switch (setting->Category()) { + case Settings::Category::Core: + core_hold[setting->GetLabel()] = widget; break; - case ConfigurationShared::CheckState::Count: + case Settings::Category::System: + system_hold[setting->IsEnum()].insert(std::pair{setting->GetLabel(), widget}); break; + default: + delete widget; } } + for (const auto& [label, widget] : core_hold) { + core_layout.addWidget(widget); + } + for (const auto& [label, widget] : system_hold[true]) { + system_layout.addWidget(widget); + } + for (const auto& [label, widget] : system_hold[false]) { + system_layout.addWidget(widget); + } } -void ConfigureSystem::SetupPerGameUI() { - if (Settings::IsConfiguringGlobal()) { - ui->combo_language->setEnabled(Settings::values.language_index.UsingGlobal()); - ui->combo_region->setEnabled(Settings::values.region_index.UsingGlobal()); - ui->combo_time_zone->setEnabled(Settings::values.time_zone_index.UsingGlobal()); - ui->rng_seed_checkbox->setEnabled(Settings::values.rng_seed.UsingGlobal()); - ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.UsingGlobal()); +void ConfigureSystem::SetConfiguration() {} - return; +void ConfigureSystem::ApplyConfiguration() { + const bool powered_on = system.IsPoweredOn(); + for (const auto& func : apply_funcs) { + func(powered_on); } - - ConfigurationShared::SetColoredComboBox(ui->combo_language, ui->label_language, - Settings::values.language_index.GetValue(true)); - ConfigurationShared::SetColoredComboBox(ui->combo_region, ui->label_region, - Settings::values.region_index.GetValue(true)); - ConfigurationShared::SetColoredComboBox(ui->combo_time_zone, ui->label_timezone, - Settings::values.time_zone_index.GetValue(true)); - - ConfigurationShared::SetColoredTristate( - ui->rng_seed_checkbox, Settings::values.rng_seed.UsingGlobal(), - Settings::values.rng_seed_enabled.GetValue(), - Settings::values.rng_seed_enabled.GetValue(true), use_rng_seed); - - ConfigurationShared::SetColoredTristate(ui->use_unsafe_extended_memory_layout, - Settings::values.use_unsafe_extended_memory_layout, - use_unsafe_extended_memory_layout); - - ui->custom_rtc_checkbox->setVisible(false); - ui->custom_rtc_edit->setVisible(false); } diff --git a/src/yuzu/configuration/configure_system.h b/src/yuzu/configuration/configure_system.h index 6064b5b40..87b575060 100644 --- a/src/yuzu/configuration/configure_system.h +++ b/src/yuzu/configuration/configure_system.h @@ -3,11 +3,15 @@ #pragma once +#include +#include #include #include #include "yuzu/configuration/configuration_shared.h" +class QDateTimeEdit; + namespace Core { class System; } @@ -20,6 +24,7 @@ class ConfigureSystem : public ConfigurationShared::Tab { public: explicit ConfigureSystem(Core::System& system_, std::shared_ptr> group, + ConfigurationShared::TranslationMap& translations, QWidget* parent = nullptr); ~ConfigureSystem() override; @@ -30,9 +35,9 @@ private: void changeEvent(QEvent* event) override; void RetranslateUI(); - void ReadSystemSettings(); + void Setup(); - void SetupPerGameUI(); + std::forward_list> apply_funcs{}; std::unique_ptr ui; bool enabled = false; @@ -41,4 +46,12 @@ private: ConfigurationShared::CheckState use_unsafe_extended_memory_layout; Core::System& system; + ConfigurationShared::TranslationMap& translations; + + QCheckBox* rng_seed_checkbox; + QLineEdit* rng_seed_edit; + QCheckBox* custom_rtc_checkbox; + QDateTimeEdit* custom_rtc_edit; + QComboBox* combo_region; + QComboBox* combo_language; }; diff --git a/src/yuzu/configuration/configure_system.ui b/src/yuzu/configuration/configure_system.ui index e0caecd5e..a5a3e2dc3 100644 --- a/src/yuzu/configuration/configure_system.ui +++ b/src/yuzu/configuration/configure_system.ui @@ -6,7 +6,7 @@ 0 0 - 366 + 605 483 @@ -22,470 +22,53 @@ - System Settings + System - - - - - Region: - - - - - - - - Auto - - - - - Default - - - - - CET - - - - - CST6CDT - - - - - Cuba - - - - - EET - - - - - Egypt - - - - - Eire - - - - - EST - - - - - EST5EDT - - - - - GB - - - - - GB-Eire - - - - - GMT - - - - - GMT+0 - - - - - GMT-0 - - - - - GMT0 - - - - - Greenwich - - - - - Hongkong - - - - - HST - - - - - Iceland - - - - - Iran - - - - - Israel - - - - - Jamaica - - - - - Japan - - - - - Kwajalein - - - - - Libya - - - - - MET - - - - - MST - - - - - MST7MDT - - - - - Navajo - - - - - NZ - - - - - NZ-CHAT - - - - - Poland - - - - - Portugal - - - - - PRC - - - - - PST8PDT - - - - - ROC - - - - - ROK - - - - - Singapore - - - - - Turkey - - - - - UCT - - - - - Universal - - - - - UTC - - - - - W-SU - - - - - WET - - - - - Zulu - - - - - - - - - Japan - - - - - USA - - - - - Europe - - - - - Australia - - - - - China - - - - - Korea - - - - - Taiwan - - - - - - - - Time Zone: - - - - - - - Note: this can be overridden when region setting is auto-select - - - - Japanese (日本語) - - - - - American English - - - - - French (français) - - - - - German (Deutsch) - - - - - Italian (italiano) - - - - - Spanish (español) - - - - - Chinese - - - - - Korean (한국어) - - - - - Dutch (Nederlands) - - - - - Portuguese (português) - - - - - Russian (Русский) - - - - - Taiwanese - - - - - British English - - - - - Canadian French - - - - - Latin American Spanish - - - - - Simplified Chinese - - - - - Traditional Chinese (正體中文) - - - - - Brazilian Portuguese (português do Brasil) - - - - - - - - Custom RTC - - - - - - - Language - - - - - - - RNG Seed - - - - - - - Device Name - - - - - - - - 1970 - 1 - 1 - - - - - - - - 128 - - - - - - - - 0 - 0 - - - - - Lucida Console - - - - HHHHHHHH - - - 8 - - - - - - - Unsafe extended memory layout (8GB DRAM) - - - - + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + Core + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + @@ -506,7 +89,7 @@ - + true diff --git a/src/yuzu/configuration/shared_translation.cpp b/src/yuzu/configuration/shared_translation.cpp index d38815e77..dc9f15cdd 100644 --- a/src/yuzu/configuration/shared_translation.cpp +++ b/src/yuzu/configuration/shared_translation.cpp @@ -109,15 +109,16 @@ std::unique_ptr InitializeTranslations(QWidget* parent) { // System INSERT(Settings, rng_seed_enabled, "RNG Seed", ""); - INSERT(Settings, rng_seed, "RNG Seed", ""); + INSERT(Settings, rng_seed, "", ""); INSERT(Settings, device_name, "Device Name", ""); INSERT(Settings, custom_rtc_enabled, "Custom RTC", ""); - INSERT(Settings, custom_rtc, "Custom RTC", ""); + INSERT(Settings, custom_rtc, "", ""); INSERT(Settings, language_index, "Language:", ""); INSERT(Settings, region_index, "Region:", ""); INSERT(Settings, time_zone_index, "Time Zone:", ""); INSERT(Settings, sound_index, "Sound Output Mode:", ""); INSERT(Settings, use_docked_mode, "", ""); + INSERT(Settings, current_user, "", ""); // Controls @@ -231,6 +232,44 @@ std::forward_list ComboboxEnumeration(std::type_index type, QWidget* pa return { tr("Automatic"), tr("Default"), tr("2x"), tr("4x"), tr("8x"), tr("16x"), }; + } else if (type == typeid(Settings::Language)) { + return { + tr("Japanese (日本語)"), + tr("American English"), + tr("French (français)"), + tr("German (Deutsch)"), + tr("Italian (italiano)"), + tr("Spanish (español)"), + tr("Chinese"), + tr("Korean (한국어)"), + tr("Dutch (Nederlands)"), + tr("Portuguese (português)"), + tr("Russian (Русский)"), + tr("Taiwanese"), + tr("British English"), + tr("Canadian French"), + tr("Latin American Spanish"), + tr("Simplified Chinese"), + tr("Traditional Chinese (正體中文)"), + tr("Brazilian Portuguese (português do Brasil)"), + }; + } else if (type == typeid(Settings::Region)) { + return { + tr("Japan"), tr("USA"), tr("Europe"), tr("Australia"), + tr("China"), tr("Korea"), tr("Taiwan"), + }; + } else if (type == typeid(Settings::TimeZone)) { + return { + tr("Auto"), tr("Default"), tr("CET"), tr("CST6CDT"), tr("Cuba"), + tr("EET"), tr("Egypt"), tr("Eire"), tr("EST"), tr("EST5EDT"), + tr("GB"), tr("GB-Eire"), tr("GMT"), tr("GMT+0"), tr("GMT-0"), + tr("GMT0"), tr("Greenwich"), tr("Hongkong"), tr("HST"), tr("Iceland"), + tr("Iran"), tr("Israel"), tr("Jamaica"), tr("Kwajalein"), tr("Libya"), + tr("MET"), tr("MST"), tr("MST7MDT"), tr("Navajo"), tr("NZ"), + tr("NZ-CHAT"), tr("Poland"), tr("Portugal"), tr("PRC"), tr("PST8PDT"), + tr("ROC"), tr("ROK"), tr("Singapore"), tr("Turkey"), tr("UCT"), + tr("W-SU"), tr("WET"), tr("Zulu"), + }; } return {}; diff --git a/src/yuzu/configuration/shared_widget.cpp b/src/yuzu/configuration/shared_widget.cpp index d1113f793..0d553c67f 100644 --- a/src/yuzu/configuration/shared_widget.cpp +++ b/src/yuzu/configuration/shared_widget.cpp @@ -1,5 +1,7 @@ #include +#include #include +#include #include #include #include @@ -9,6 +11,9 @@ #include #include #include +#include +#include +#include #include "common/common_types.h" #include "common/settings.h" #include "yuzu/configuration/configuration_shared.h" @@ -25,7 +30,7 @@ QPushButton* Widget::CreateRestoreGlobalButton(Settings::BasicSetting& setting, QStyle* style = parent->style(); QIcon* icon = new QIcon(style->standardIcon(QStyle::SP_DialogResetButton)); QPushButton* restore_button = new QPushButton(*icon, QStringLiteral(""), parent); - restore_button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding); + restore_button->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred); QSizePolicy sp_retain = restore_button->sizePolicy(); sp_retain.setRetainSizeWhenHidden(true); @@ -241,6 +246,67 @@ void Widget::CreateSlider(const QString& name, bool reversed, float multiplier, } } +void Widget::CreateCheckBoxWithHexEdit(const QString& label, Settings::BasicSetting* other_setting, + std::function& load_func) { + if (other_setting == nullptr) { + LOG_WARNING(Frontend, "Extra setting is null or not an integer"); + return; + } + created = true; + + std::function checkbox_load_func; + CreateCheckBox(label, checkbox_load_func); + + auto to_hex = [=](const std::string& input) { + return QString::fromStdString(fmt::format("{:08x}", std::stoi(input))); + }; + + QHBoxLayout* layout = reinterpret_cast(this->layout()); + const QString default_val = to_hex(other_setting->ToString()); + + line_edit = new QLineEdit(this); + line_edit->setText(default_val); + + checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + layout->insertWidget(1, line_edit); + + line_edit->setMaxLength(8); + QRegExpValidator* regex = + new QRegExpValidator{QRegExp{QStringLiteral("^[0-9a-fA-F]{0,8}$")}, line_edit}; + line_edit->setValidator(regex); + + auto hex_to_dec = [=]() -> std::string { + return std::to_string(std::stoul(line_edit->text().toStdString(), nullptr, 16)); + }; + + if (Settings::IsConfiguringGlobal()) { + load_func = [=]() { + checkbox_load_func(); + other_setting->LoadString(hex_to_dec()); + }; + } else { + QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) { + line_edit->setText(to_hex(other_setting->ToStringGlobal())); + }); + + QObject::connect(line_edit, &QLineEdit::textEdited, [=](const QString&) { + restore_button->setEnabled(true); + restore_button->setVisible(true); + }); + + load_func = [=]() { + checkbox_load_func(); + + const bool using_global = !restore_button->isEnabled(); + other_setting->SetGlobal(using_global); + if (!using_global) { + other_setting->LoadString(hex_to_dec()); + } + }; + } +} + void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSetting* other_setting, std::function& load_func) { if (other_setting == nullptr) { @@ -268,8 +334,9 @@ void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSet other_setting->LoadString(line_edit->text().toStdString()); }; } else { - QObject::connect(restore_button, &QAbstractButton::clicked, - [=](bool) { line_edit->setText(default_val); }); + QObject::connect(restore_button, &QAbstractButton::clicked, [=](bool) { + line_edit->setText(QString::fromStdString(other_setting->ToStringGlobal())); + }); QObject::connect(line_edit, &QLineEdit::textEdited, [=](const QString&) { restore_button->setEnabled(true); @@ -279,7 +346,7 @@ void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSet load_func = [=]() { checkbox_load_func(); - const bool using_global = !restore_button->isVisible(); + const bool using_global = !restore_button->isEnabled(); other_setting->SetGlobal(using_global); if (!using_global) { other_setting->LoadString(line_edit->text().toStdString()); @@ -289,7 +356,8 @@ void Widget::CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSet } void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSetting* other_setting, - std::function& load_func, const QString& suffix) { + std::function& load_func, + const std::string& suffix) { if (other_setting == nullptr && IsInt(other_setting->TypeId())) { LOG_WARNING(Frontend, "Extra setting is null or not an integer"); return; @@ -308,7 +376,7 @@ void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSett const int default_val = std::stoi(other_setting->ToString()); spinbox->setRange(min_val, max_val); spinbox->setValue(default_val); - spinbox->setSuffix(suffix); + spinbox->setSuffix(QString::fromStdString(suffix)); spinbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); layout->insertWidget(1, spinbox); @@ -320,7 +388,7 @@ void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSett }; } else { QObject::connect(restore_button, &QAbstractButton::clicked, [this, other_setting](bool) { - spinbox->setValue(std::stoi(other_setting->ToString())); + spinbox->setValue(std::stoi(other_setting->ToStringGlobal())); }); QObject::connect(spinbox, QOverload::of(&QSpinBox::valueChanged), [this](int) { @@ -331,7 +399,7 @@ void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSett load_func = [=]() { checkbox_load_func(); - const bool using_global = !restore_button->isVisible(); + const bool using_global = !restore_button->isEnabled(); other_setting->SetGlobal(using_global); if (!using_global) { other_setting->LoadString(std::to_string(spinbox->value())); @@ -340,6 +408,81 @@ void Widget::CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSett } } +// Currently tailored to custom_rtc +void Widget::CreateCheckBoxWithDateTimeEdit(const QString& label, + Settings::BasicSetting* other_setting, + std::function& load_func) { + if (other_setting == nullptr) { + LOG_WARNING(Frontend, "Extra setting is null or not an integer"); + return; + } + created = true; + + std::function checkbox_load_func; + CreateCheckBox(label, checkbox_load_func); + + QHBoxLayout* layout = reinterpret_cast(this->layout()); + const bool disabled = setting.ToString() != "true"; + const long long current_time = QDateTime::currentSecsSinceEpoch(); + const s64 the_time = disabled ? current_time : std::stoll(other_setting->ToString()); + const auto default_val = QDateTime::fromSecsSinceEpoch(the_time); + + date_time_edit = new QDateTimeEdit(this); + date_time_edit->setDateTime(default_val); + + date_time_edit->setMinimumDateTime(QDateTime::fromSecsSinceEpoch(0)); + + date_time_edit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + checkbox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + + layout->insertWidget(1, date_time_edit); + + if (Settings::IsConfiguringGlobal()) { + load_func = [=]() { + checkbox_load_func(); + if (checkbox->checkState() == Qt::Unchecked) { + return; + } + + other_setting->LoadString( + std::to_string(date_time_edit->dateTime().toSecsSinceEpoch())); + }; + } else { + auto get_clear_val = [=]() { + return QDateTime::fromSecsSinceEpoch([=]() { + if (checkbox->checkState() == Qt::Checked) { + return std::stoll(other_setting->ToStringGlobal()); + } + return current_time; + }()); + }; + + QObject::connect(restore_button, &QAbstractButton::clicked, + [=](bool) { date_time_edit->setDateTime(get_clear_val()); }); + + QObject::connect(date_time_edit, &QDateTimeEdit::editingFinished, [=]() { + if (date_time_edit->dateTime() != get_clear_val()) { + restore_button->setEnabled(true); + restore_button->setVisible(true); + } + }); + + load_func = [=]() { + checkbox_load_func(); + if (checkbox->checkState() == Qt::Unchecked) { + return; + } + + const bool using_global = !restore_button->isEnabled(); + other_setting->SetGlobal(using_global); + if (!using_global) { + other_setting->LoadString( + std::to_string(date_time_edit->dateTime().toSecsSinceEpoch())); + } + }; + } +} + bool Widget::Valid() { return created; } @@ -350,7 +493,7 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati QWidget* parent_, bool runtime_lock, std::forward_list>& apply_funcs, RequestType request, bool managed, float multiplier, Settings::BasicSetting* other_setting, - const QString& format) + const std::string& string) : QWidget(parent_), parent{parent_}, translations{translations_}, setting{*setting_} { if (!Settings::IsConfiguringGlobal() && !setting.Switchable()) { LOG_DEBUG(Frontend, "\"{}\" is not switchable, skipping...", setting.GetLabel()); @@ -379,19 +522,26 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati if (type == typeid(bool)) { switch (request) { - case RequestType::SpinBox: - CreateCheckBoxWithSpinBox(label, other_setting, load_func, format); - break; case RequestType::Default: CreateCheckBox(label, load_func); break; + case RequestType::SpinBox: + CreateCheckBoxWithSpinBox(label, other_setting, load_func, string); + break; + case RequestType::HexEdit: + CreateCheckBoxWithHexEdit(label, other_setting, load_func); + break; case RequestType::LineEdit: CreateCheckBoxWithLineEdit(label, other_setting, load_func); break; + case RequestType::DateTimeEdit: + CreateCheckBoxWithDateTimeEdit(label, other_setting, load_func); + break; case RequestType::ComboBox: case RequestType::Slider: case RequestType::ReverseSlider: case RequestType::MaxEnum: + LOG_DEBUG(Frontend, "Requested widget is unimplemented."); break; } } else if (setting.IsEnum()) { @@ -409,10 +559,15 @@ Widget::Widget(Settings::BasicSetting* setting_, const TranslationMap& translati case RequestType::ComboBox: CreateCombobox(label, managed, load_func); break; + case RequestType::DateTimeEdit: case RequestType::SpinBox: + case RequestType::HexEdit: case RequestType::MaxEnum: + LOG_DEBUG(Frontend, "Requested widget is unimplemented."); break; } + } else if (type == typeid(std::string)) { + CreateLineEdit(label, managed, load_func); } if (!created) { diff --git a/src/yuzu/configuration/shared_widget.h b/src/yuzu/configuration/shared_widget.h index 88a864b42..9923aa2ea 100644 --- a/src/yuzu/configuration/shared_widget.h +++ b/src/yuzu/configuration/shared_widget.h @@ -9,6 +9,7 @@ class QComboBox; class QLineEdit; class QSlider; class QCheckBox; +class QDateTimeEdit; namespace Settings { class BasicSetting; @@ -23,6 +24,8 @@ enum class RequestType { Slider, ReverseSlider, LineEdit, + HexEdit, + DateTimeEdit, MaxEnum, }; @@ -33,8 +36,7 @@ public: Widget(Settings::BasicSetting* setting, const TranslationMap& translations, QWidget* parent, bool runtime_lock, std::forward_list>& apply_funcs, RequestType request = RequestType::Default, bool managed = true, float multiplier = 1.0f, - Settings::BasicSetting* other_setting = nullptr, - const QString& format = QStringLiteral("")); + Settings::BasicSetting* other_setting = nullptr, const std::string& format = ""); virtual ~Widget(); bool Valid(); @@ -48,13 +50,18 @@ public: QCheckBox* checkbox{}; QSlider* slider{}; QComboBox* combobox{}; + QDateTimeEdit* date_time_edit{}; private: void CreateCheckBox(const QString& label, std::function& load_func); void CreateCheckBoxWithLineEdit(const QString& label, Settings::BasicSetting* other_setting, std::function& load_func); + void CreateCheckBoxWithHexEdit(const QString& label, Settings::BasicSetting* other_setting, + std::function& load_func); void CreateCheckBoxWithSpinBox(const QString& label, Settings::BasicSetting* other_setting, - std::function& load_func, const QString& suffix); + std::function& load_func, const std::string& suffix); + void CreateCheckBoxWithDateTimeEdit(const QString& label, Settings::BasicSetting* other_setting, + std::function& load_func); void CreateCombobox(const QString& label, bool managed, std::function& load_func); void CreateLineEdit(const QString& label, bool managed, std::function& load_func); void CreateSlider(const QString& label, bool reversed, float multiplier, diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index f8cbf8034..c42d98709 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -229,6 +229,7 @@ void Config::ReadValues() { ReadCategory(Settings::Category::RendererAdvanced); ReadCategory(Settings::Category::RendererDebug); ReadCategory(Settings::Category::System); + ReadCategory(Settings::Category::SystemAudio); ReadCategory(Settings::Category::DataStorage); ReadCategory(Settings::Category::Debugging); ReadCategory(Settings::Category::DebuggingGraphics); -- cgit v1.2.3